package com.wyy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wyy.beans.User;
import com.wyy.beans.UserRole;
import com.wyy.common.Result;
import com.wyy.dao.UserDao;
import com.wyy.dao.UserRoleDao;
import com.wyy.service.UserService;
import com.wyy.util.MD5Util;
import com.wyy.util.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.coyote.Request;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public Result<User> login(User user) {
        Subject subject = SecurityUtils.getSubject();
        String password = MD5Util.getMD5(user.getPassword());
        UsernamePasswordToken token = new UsernamePasswordToken(
                user.getTelephoneNumber(),
                password);
        try {
            subject.login(token);
            subject.checkRoles();

            return new Result<>(Result.ResultStatus.SUCCESS.code, "登录成功");
        }  catch (Exception e) {
            e.printStackTrace();
        }

        return new Result<>(Result.ResultStatus.Failed.code, "登录失败");
    }

    @Override
    public Result<String> loginOut() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return new Result<>(Result.ResultStatus.SUCCESS.code, "success");
    }

    @Override
    public Result<User> addUser(User user) {
        if (StringUtils.isBlank(user.getUsername()) ||
                StringUtils.isBlank(user.getPassword())) {
            return new Result<>(Result.ResultStatus.Failed.code,
                    "用户名或密码为空");
        }

        Result<User> userResult = getUserByTelephoneNumber(user.getTelephoneNumber());
        if (userResult.getStatus() == 200){
            return new Result<>(Result.ResultStatus.Failed.code, "此用户已存在");
        }

        user.setPassword(MD5Util.getMD5(user.getPassword()));
        int aff = userDao.insert(user);
        if (user.getRoles() != null) {
            user.getRoles().forEach(
                    role -> userRoleDao.insert(
                            new UserRole(user.getUid(), role.getRid())));
        }
        return aff == 0 ? new Result<>(Result.ResultStatus.Failed.code, "fail")
                : new Result<>(Result.ResultStatus.SUCCESS.code, "success");
    }

    @Override
    public Result<User> deleteUser(long uid) {

        User user = userDao.selectById(uid);
        redisUtils.delete(user.getTelephoneNumber());
        redisUtils.delete(user.getTelephoneNumber() + "roles");
        redisUtils.delete(user.getTelephoneNumber() + "resources");

        userDao.deleteById(uid);
        userRoleDao.deleteUserRoleByUserId(uid);

        return new Result<>(Result.ResultStatus.SUCCESS.code, "success");
    }

    @Override
    public Result<User> updateUser(User user) {
        Result<User> userResult = getUserByTelephoneNumber(user.getTelephoneNumber());
        if (userResult.getStatus() == 500){
            return new Result<>(Result.ResultStatus.Failed.code, "此用户不存在");
        }

        redisUtils.delete(user.getTelephoneNumber());
        redisUtils.delete(user.getTelephoneNumber() + "roles");
        redisUtils.delete(user.getTelephoneNumber() + "resources");

        user.setUid(userResult.getData().getUid());
        user.setPassword(MD5Util.getMD5(userResult.getData().getPassword()));
        int aff = userDao.updateById(user);
        if (user.getRoles() != null) {
            userRoleDao.deleteUserRoleByUserId(user.getUid());
            user.getRoles().forEach(
                    role -> userRoleDao.insert(
                            new UserRole(user.getUid(), role.getRid())));
        }
        return aff == 0 ? new Result<>(Result.ResultStatus.Failed.code, "fail")
                : new Result<>(Result.ResultStatus.SUCCESS.code, "success");
    }

    @Override
    public Result<User> getUserByTelephoneNumber(String telephoneNumber) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(true, "telephone_number", telephoneNumber);
        User user = userDao.selectOne(queryWrapper);
        return user == null
                ? new Result<>(Result.ResultStatus.Failed.code, "该用户不存在")
                : new Result<>(Result.ResultStatus.SUCCESS.code, "success", user);
    }

    @Override
    public Result<User> getUserById(long id) {
        User user = userDao.selectById(id);
        return user == null
                ? new Result<>(Result.ResultStatus.Failed.code, "该用户不存在")
                : new Result<>(Result.ResultStatus.SUCCESS.code, "success", user);
    }
}
